package com.lijiajia.cloud.authserver.security;

import com.lijiajia.cloud.authserver.pojo.mongodb.Menu;
import com.lijiajia.cloud.authserver.pojo.mongodb.Role;
import com.lijiajia.cloud.authserver.pojo.mongodb.User;
import com.lijiajia.cloud.authserver.service.MenuService;
import com.lijiajia.cloud.authserver.service.RoleService;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 基础用户服务
 *
 * @author lijiajia
 * @since 2019-05-22
 */
public class BaseUserService {
    private final RoleService roleService;
    private final MenuService menuService;

    public BaseUserService(RoleService roleService, MenuService menuService) {
        this.roleService = roleService;
        this.menuService = menuService;
    }

    /**
     * 构建 baseUser
     *
     * @param user 用户
     * @return 用户
     */
    protected BaseUser buildUser(User user) {
        // 角色
        Collection<String> roleIds = Collections.emptySet();

        // 权限
        Collection<String> authorities = Collections.emptySet();
        if (user.getRoleIds() != null && !user.getRoleIds().isEmpty()) {
            List<Role> roles = roleService.findByIds(user.getRoleIds());
            if (!roles.isEmpty()) {
                roleIds = user.getRoleIds();
                Set<Long> menuIds = roles.stream()
                        .map(Role::getMenuIds)
                        .collect(Collectors.collectingAndThen(
                                Collectors.toList(),
                                roleMenuIds -> {
                                    Set<Long> allRoleMenuIds = new HashSet<>();
                                    roleMenuIds.forEach(allRoleMenuIds::addAll);
                                    return allRoleMenuIds;
                                }));
                List<Menu> menus = menuService.findByIds(menuIds);
                if (!menus.isEmpty()) {
                    authorities = menus.stream()
                            .map(Menu::getAuthorityIds)
                            .filter(menuId -> menuId != null && !menuId.isEmpty())
                            .collect(Collectors.collectingAndThen(
                                    Collectors.toList(),
                                    menuAuthorityIds -> {
                                        Set<String> allAuthorityIds = new HashSet<>();
                                        menuAuthorityIds.forEach(allAuthorityIds::addAll);
                                        return allAuthorityIds;
                                    }
                            ));
                }
            }
        }
        List<String> userAuthorities = new ArrayList<>();
        userAuthorities.addAll(roleIds);
        userAuthorities.addAll(authorities);

        return new BaseUser()
                .setUserId(user.getId())
                .setLoginName(user.getUsername())
                .setPassword(user.getPassword())
                .setAuthorities(userAuthorities.stream()
                        .map(SimpleGrantedAuthority::new)
                        .collect(Collectors.toUnmodifiableSet()))
                .setTelephone(user.getTelephone())
                .setEmail(user.getEmail())
                .setAvatar(user.getAvatar())
                .setJoinTime(user.getCreatedAt())
                .setRealName(user.getRealName())
                .setEnabled(user.getEnabled())
                .setDeleted(user.getDeleted());
    }
}
